#include <iostream>
#include <typeinfo>
#include <any>//使用c++17库
#include <string>
#include <type_traits>
#include <utility>

class my_any{
private:
    class basic{
    public:
        virtual const std::type_info& type() = 0;//返回存储数据的类型
        virtual basic* clone() = 0;//构造一个与自身数据相同的对象，方便拷贝构造
    };
    template<class T>
    class derive : basic{
    public:
        derive(T val)
        :_val(val)
        {}

        virtual const std::type_info& type()
        {
            return typeid(T);
        }

        virtual derive* clone()
        {
            return new derive<T>(_val);
        }
        T _val;
    };
    basic* _content;
public:
    my_any()
    :_content(nullptr)
    {}

    template<class T>
    my_any(const T& val)
    :_content((basic*)new derive<T>(val))
    {}

    my_any(const my_any& a)
    {
        if(a._content == nullptr)
        {
            _content = nullptr;
        }
        else
        {
            _content = a._content->clone();
        }
    }

    ~my_any()
    {
        delete(_content);
    }

    my_any& swap(my_any &a)//方便赋值运算符重载，对临时对象进行自动释放
    {
        std::swap(_content, a._content);
        return *this;
    }

    template<class T>
    my_any& operator=(const T& val)
    {
        my_any(val).swap(*this);
        return *this;
    }

    my_any& operator=(const my_any& a)
    {
        my_any(a).swap(*this);
        return *this;
    }

    template<class T>
    T* get()
    {
        if(typeid(T) == _content->type())
        {
            return &(((derive<T>*)_content)->_val);
        }
        else
        {
            std::cout << "类型不匹配" << std:: endl;
        }
    }
};

class test{
    public:
    test()
    {
        std::cout << "构造" << std::endl;
    }
    test(const test& t)
    {
        std::cout << "拷贝" << std::endl;
    }
    ~test()
    {
        std::cout << "析构" << std::endl;
    }
};

int main()
{
    //  my_any a;
    //  a = 10;
    //  int* ret = a.get<int>();

    //  std::cout << *ret << std::endl;

    // my_any a;
    // test t;
    // a= t;
    // my_any b(a);

    //c++库的any
    // std::any a(10);
    // std::cout << std::any_cast<int>(a) << std::endl;
    // std::any b(std::string("abc"));
    // std::string ret = std::any_cast<std::string>(b);
    // std::cout << ret << std::endl;
    // return 0;
}